#include <iostream>
#include <string>
#include <mysql/mysql.h>

const std::string host = "localhost";
const std::string user = "connector";
const std::string password = "znsb1234";
const std::string db = "conn";
const unsigned int port = 3306;

int main()
{
    //1. 为数据库创建句柄对象，类似于C语言中的文件操作FILE* /这里是MYSQL*
    MYSQL* my = mysql_init(nullptr);
    if(my == nullptr)
    {
        std::cerr << "mysql init error" << std::endl;
        return 1; 
    }

    // 2.连接数据库，相当于在bash界面的登陆，需要用户和密码
    if(mysql_real_connect(my,host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        std::cerr << "connection MySql fail" << std::endl;
        return 2;
    }

    std::cout << "connect mysql success..." << std::endl;

    //设置编码格式, 否则中文会出现乱码
    mysql_set_character_set(my, "utf8");
    //std::string sql = "insert into user (name, skill) values ('小食堂', '网恋')";
    //std::string sql = "delete from user where id = 1";
    //std::string sql = "update user set name='马老c' where id = 2";
    // std::string sql = "insert into user (name, skill) values ('孙狗', '司马脸')";
    std::string sql = "select * from user";

    //3.对数据库进行curd操作
    int ret = mysql_query(my, sql.c_str());
    if(ret == 0)
    {
        std::cout << sql << " operation success, " << ret << std::endl;
    }
    else
    {
        std::cerr << sql << " operator error, " << ret << std::endl;
        return 3;
    }

    //将MYSQL对象中的数据转存到MYSQL_RES对象中, select之后可以这样干
    MYSQL_RES* res = mysql_store_result(my);
    if(res == nullptr)
    {
        std::cerr << "store error" << std::endl;
        return 4;
    }

    //这里是拿到select之后的数据，知道他一共有多少行多少列
    int rows = mysql_num_rows(res);
    int fields = mysql_num_fields(res);

    std::cout << "行: " << rows << std::endl;
    std::cout << "列: " << fields << std::endl;

    //我们像打印出来mysql的表头信息,mysql_fetch_fields返回所有列属性信息
    MYSQL_FIELD* fields_array = mysql_fetch_fields(res);
    for(int i = 0; i < fields; i++)
    {
        std::cout << fields_array[i].name << "\t";
    }
    std::cout << "\n";

    std::cout << fields_array[1].db << ", " <<  fields_array[1].table << std::endl;

    //将数据打印到终端显示器中
    for(int i = 0; i < rows; i++)
    {
        //这里的MYSQL_ROW其实就是char**类型的指针
        MYSQL_ROW row = mysql_fetch_row(res);
        for(int j = 0; j < fields; j++)
        {
            std::cout << row[j] << "\t";//row[j] <-> char** 类型的解引用就是char*类型就是字符串
        }

        std::cout << "\n";
    }

    //上面使用了mysql_store_result这里就一定要mysql_free_result避免内存泄漏，因为mysql_store_result函数一定是开了空间为我们存储相关信息
    mysql_free_result(res);

    //4.关闭数据库，千万要注意不要造成资源泄漏
    mysql_close(my);

    return 0;
}